class process:
  def __init__(self, name, time, ta=0):
    self.name = name
    self.elapsed_time = time
    self.time_of_arrival=ta
  def run(self):
    print(self.name)
class fifo:
  def __init__(self, pl):
    self.process_list = sorted(pl, key=lambda x: x.time_of_arrival)
  def __iter__(self):
    self.count = 0
    return self
  def __next__(self):
    if self.count >= len(self.process_list): raise StopIteration
    self.count +=1
    return self.process_list[self.count-1]
class round_robin:
  def __init__(self, pl):
    self.process_list = pl
    self.cpu_quantum = 5
  def __iter__(self):
    self.count = 0
    return self
  def __next__(self):
    if len(self.process_list) <= 0: raise StopIteration
    p = self.process_list[0]
    p.elapsed_time -= self.cpu_quantum
    self.process_list = \
       self.process_list[1:]+[p] if (p.elapsed_time > 0) else self.process_list[1:]
    return p
class scheduler:
  def __init__(self, pl,algorithm):
    self.process_list = pl
    self.iterable_scheduling = iter(algorithm(pl))
  def scheduling(self):
    try:
      while True:
        running_process = next(self.iterable_scheduling)
        running_process.run()
    except StopIteration:
      print("All Process Scheduled!!")

if __name__ == "__main__":
  pl = [process("one", 10), process("two", 3, 5), process("three", 15), \
        process("four", 30, 5), process("five", 10), process("six", 6, 10),
        process("seven", 10), process("eight", 25, 5)]
  print("fifo scheduling")
  s = scheduler(pl, fifo)
  s.scheduling()
  print("round-robin scheduling")
  s = scheduler(pl, round_robin)
  s.scheduling()

